package cn.org.bjca.seal.esspdf.client.test;

import cn.org.bjca.anysign.components.bean.message.*;
import cn.org.bjca.anysign.model.p2p.SignExtInfo;
import cn.org.bjca.anysign.terminal.model.AttachmentInfo;
import cn.org.bjca.anysign.terminal.model.CachetInfo;
import cn.org.bjca.anysign.terminal.model.KWInfo;
import cn.org.bjca.anysign.terminal.model.SignRuleInfo;
import cn.org.bjca.common.model.DocumentExtType;
import cn.org.bjca.common.model.GeneratePDFInfo;
import cn.org.bjca.common.model.KWRuleInfo;
import cn.org.bjca.common.model.PosRuleInfo;
import cn.org.bjca.seal.esspdf.client.message.ChannelMessage;
import cn.org.bjca.seal.esspdf.client.tools.AnySignClientTool;
import cn.org.bjca.seal.esspdf.client.utils.ClientUtil;
import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.*;

/***************************************************************************
 * <pre>
 *     V2.0签名单元测试
 * </pre>
 * @文件名称: AnyWriteClientToolTest.java
 * @包 路   径：  cn.org.bjca.seal.esspdf.client.test
 * @版权所有：北京数字认证股份有限公司 (C) 2017
 *
 * @类描述:
 * @版本: V2.0
 * @创建人： liuyan
 * @创建时间：2017-8-8 下午1:37:39
 *
 ***************************************************************************/
public class AnyWriteClientToolTest {

	AnySignClientTool anySignClientTool = null;

    private String resourcesPath;

    String testEncDataPath;

    String testHtmlFilePath;

    String testPdfFilePath;

    String testXMLFilePath;

    String testImageFilePath;

    String outPdfsFilePath;

    String testSignedPdfFilePath;

    private static Properties errorCodeProperties = new Properties();


	@Before
	public void init() throws Exception {
		String ip = "localhost";
		int port = 8002;
		anySignClientTool = new AnySignClientTool(ip, port);
        resourcesPath = URLDecoder.decode(this.getClass().getClassLoader().getResource("").getPath(), "UTF-8");
        testEncDataPath = resourcesPath + "encdata" + File.separator;
        testHtmlFilePath = resourcesPath + "html" + File.separator + "test.html";
        testPdfFilePath = resourcesPath + "pdf" + File.separator + "test.pdf";
        testXMLFilePath = resourcesPath + "xml" + File.separator + "test.xml";
        testImageFilePath = resourcesPath + "image" + File.separator + "test.gif";
        testSignedPdfFilePath = resourcesPath + "pdf" + File.separator + "anywriteSignedPDF.pdf";
        outPdfsFilePath = resourcesPath + "out" + File.separator;
	}

	/**
	 * <p>加密包签名</p>
	 * @Description:
	 * @return:void
	 * @throws:
	 */
	@Test
	public void testAnySignEncPackage() throws Exception { // 加密包签名
		byte[] encDataBty = ClientUtil.readFileToByteArray(new File(testEncDataPath + "手写签名加密包.txt"));// 加密包字节数组
		long begin = System.currentTimeMillis();
		ChannelMessage message = anySignClientTool.anyWriteEncPackage(encDataBty);
		long end = System.currentTimeMillis();
		System.out.println("********************运行时间:" + (end - begin) / 1000f + "s");
		System.out.println("状态码：" + message.getStatusCode());
		System.out.println("状态信息：" + message.getStatusInfo());
		Assert.assertEquals("200", message.getStatusCode());
		if ("200".equals(message.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			List<MessageBodyReference> messageBodyReferenceList = message.getMessageBodyReferenceList();
			MessageBodyReference messageBodyReference = null;
			for (int i = 0; i < messageBodyReferenceList.size(); i++) {
				messageBodyReference = messageBodyReferenceList.get(i);
				ClientUtil.writeByteArrayToFile(new File(outPdfsFilePath + "testAnySignEncPackage_" + i + ".pdf"), messageBodyReference.getFileBty());
			}
		}
	}

	/**
	 * <p>多加密包手写签名</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testAnyWritePDFFacade() throws Exception { // 手写签名门面
		byte[] encDataBty = ClientUtil.readFileToByteArray(new File(testEncDataPath + "手写签名加密包.txt"));// 加密包字节数组
		List<ExternalAnyWriteInfo> externalAnyWriteInfoList = new ArrayList<ExternalAnyWriteInfo>();
		ExternalAnyWriteInfo externalAnyWriteInfo = null;
		List<ExternalEncryptPackageInfo> encryptPackageInfoList = null;
		for (int i = 0; i < 2; i++) {
			externalAnyWriteInfo = new ExternalAnyWriteInfo();
			externalAnyWriteInfo.setChannel("999999");
			ExternalEncryptPackageInfo encryptPackageInfo = null;
			encryptPackageInfoList = new ArrayList<ExternalEncryptPackageInfo>();
			for (int j = 0; j < 2; j++) {
				encryptPackageInfo = new ExternalEncryptPackageInfo(encDataBty);
				Map<Integer, List<AttachmentInfo>> evidenceMap = new HashMap<Integer, List<AttachmentInfo>>();
				List<AttachmentInfo> evidenceList1 = new ArrayList<AttachmentInfo>();
				List<AttachmentInfo> evidenceList2 = new ArrayList<AttachmentInfo>();
				AttachmentInfo evidence1 = new AttachmentInfo();
				evidence1.setFormat(DocumentExtType.IMAGEGIF.name());
				evidence1.setPointHash("222222222222222222222222222222222222222222");
				evidenceList1.add(evidence1);
				AttachmentInfo evidence2 = new AttachmentInfo();
				evidence2.setFormat(DocumentExtType.IMAGEGIF.name());
				evidence2.setPointHash("11111111111111111111111111111111111111111");
				evidenceList1.add(evidence2);
				evidenceMap.put(1, evidenceList1);
				evidenceList2.add(evidence1);
				evidenceList2.add(evidence2);
				evidenceMap.put(2, evidenceList2);
				encryptPackageInfo.setEvidenceList(evidenceMap);
				encryptPackageInfoList.add(encryptPackageInfo);
			}
			externalAnyWriteInfo.setEncryptPackageInfoList(encryptPackageInfoList);
			externalAnyWriteInfoList.add(externalAnyWriteInfo);
		}

		long begin = System.currentTimeMillis();
		ChannelMessage message = anySignClientTool.anyWritePDFSignFacade(externalAnyWriteInfoList);
		long end = System.currentTimeMillis();
		System.out.println("********************运行时间:" + (end - begin) / 1000f + "s");
		System.out.println("状态码：" + message.getStatusCode());
		System.out.println("状态信息：" + message.getStatusInfo());
		Assert.assertEquals("200", message.getStatusCode());
		if ("200".equals(message.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			List<MessageBodyReference> messageBodyReferenceList = message.getMessageBodyReferenceList();
			MessageBodyReference messageBodyReference = null;
			for (int i = 0; i < messageBodyReferenceList.size(); i++) {
				messageBodyReference = messageBodyReferenceList.get(i);
				ClientUtil.writeByteArrayToFile(new File(outPdfsFilePath + "testAnyWritePDFFacade_" + i + ".pdf"), messageBodyReference.getFileBty());
			}
		}
	}

	/**
	 * <p>一名多签测试用例</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testMultiPDFAnyWriteSignBySingleName() throws Exception {
		byte[] encDataBty = ClientUtil.readFileToByteArray(new File(testEncDataPath + "手写签名加密包.txt"));// 加密包字节数组
		List<ExternalAnyWriteInfo> externalAnyWriteInfoList = new ArrayList<ExternalAnyWriteInfo>(1);
		ExternalAnyWriteInfo externalAnyWriteInfo = null;
		externalAnyWriteInfo = new ExternalAnyWriteInfo();
		externalAnyWriteInfo.setChannel("999999");
		ExternalEncryptPackageInfo encryptPackageInfo = new ExternalEncryptPackageInfo(encDataBty);

		byte[] pdfBty1 = ClientUtil.readFileToByteArray(new File(testHtmlFilePath));// PDF字节数组
		List<GeneratePDFInfo> generatePDFInfoList = new ArrayList<GeneratePDFInfo>();
		GeneratePDFInfo generatePDFInfo = null;
		for (int i = 0; i < 10; i++) {
			generatePDFInfo = new GeneratePDFInfo();
			generatePDFInfo.setDocContent(pdfBty1);
			generatePDFInfo.setDocumentExtType(DocumentExtType.HTML);
			generatePDFInfoList.add(generatePDFInfo);
		}
		List<ExternalEncryptPackageInfo> encryptPackageInfoList = new ArrayList<ExternalEncryptPackageInfo>();
		encryptPackageInfoList.add(encryptPackageInfo);
		externalAnyWriteInfo.setEncryptPackageInfoList(encryptPackageInfoList);
		externalAnyWriteInfo.setGeneratePDFInfoList(generatePDFInfoList);
		externalAnyWriteInfoList.add(externalAnyWriteInfo);
		long begin = System.currentTimeMillis();
		ChannelMessage message = anySignClientTool.anyWritePDFSignFacade(externalAnyWriteInfoList);
		long end = System.currentTimeMillis();
		System.out.println("********************运行时间:" + (end - begin) / 1000f + "s");
		System.out.println("状态码：" + message.getStatusCode());
		System.out.println("状态信息：" + message.getStatusInfo());
		Assert.assertEquals("200", message.getStatusCode());
		if ("200".equals(message.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			List<MessageBodyReference> messageBodyReferenceList = message.getMessageBodyReferenceList();
			MessageBodyReference messageBodyReference = null;
			for (int i = 0; i < messageBodyReferenceList.size(); i++) {
				messageBodyReference = messageBodyReferenceList.get(i);
				ClientUtil.writeByteArrayToFile(new File(outPdfsFilePath + "testMultiPDFAnyWriteSignBySingleName_" + i + ".pdf"), messageBodyReference.getFileBty());
			}
		}
	}

	/**
	 * <p>生成PDF并手写签名</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testGenPDFAndSign() throws Exception {
		byte[] xmlBty1 = ClientUtil.readFileToByteArray(new File(testHtmlFilePath));// 加密包字节数组

		List<ExternalAnyWriteInfo> externalAnyWriteInfoList = new ArrayList<ExternalAnyWriteInfo>(1);
		ExternalAnyWriteInfo externalAnyWriteInfo = null;
		externalAnyWriteInfo = new ExternalAnyWriteInfo();
		externalAnyWriteInfo.setChannel("999999");

		List<GeneratePDFInfo> generatePDFInfoList = new ArrayList<GeneratePDFInfo>();
		GeneratePDFInfo generatePDFInfo = null;
		for (int i = 0; i < 1; i++) {
			generatePDFInfo = new GeneratePDFInfo();
			generatePDFInfo.setDocContent(xmlBty1);
			generatePDFInfo.setDocumentExtType(DocumentExtType.HTML);
			// generatePDFInfo.setDocStyleTid("3995D49B5C7A9F54");
			generatePDFInfoList.add(generatePDFInfo);
		}
		externalAnyWriteInfo.setGeneratePDFInfoList(generatePDFInfoList);
		externalAnyWriteInfoList.add(externalAnyWriteInfo);

		long begin = System.currentTimeMillis();
		ChannelMessage message = anySignClientTool.anyWritePDFSignFacade(externalAnyWriteInfoList);
		long end = System.currentTimeMillis();
		System.out.println("********************运行时间:" + (end - begin) / 1000f + "s");
		System.out.println("状态码：" + message.getStatusCode());
		System.out.println("状态信息：" + message.getStatusInfo());
		Assert.assertEquals("200", message.getStatusCode());
		if ("200".equals(message.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			List<MessageBodyReference> messageBodyReferenceList = message.getMessageBodyReferenceList();
			MessageBodyReference messageBodyReference = null;
			for (int i = 0; i < messageBodyReferenceList.size(); i++) {
				messageBodyReference = messageBodyReferenceList.get(i);
				ClientUtil.writeByteArrayToFile(new File(outPdfsFilePath + "testGenPDFAndSign_" + i + ".pdf"), messageBodyReference.getFileBty());
			}
		}
	}

	/**
	 * <p>数据签名</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testAnyWriteDataSign() throws Exception {
		String pathname = testEncDataPath + "数据签名加密包.txt";
		byte[] encPackage = FileUtils.readFileToByteArray(new File(pathname));
		ChannelMessage message = anySignClientTool.anyWriteDataSign(encPackage);
		System.out.println("状态码：" + message.getStatusCode());
		System.out.println("状态信息：" + message.getStatusInfo());
		Assert.assertEquals("200", message.getStatusCode());
		if ("200".equals(message.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			ClientUtil.writeByteArrayToFile(new File(outPdfsFilePath + "testAnyWriteDataSign.txt"), message.getBody());
		}
	}

	/**
	 * <p>数据签名验证</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testAnyWriteDataVerify() throws Exception {
		String contents = "x+uy4srUyrHKudPDuLTU07XE1K3OxLvyyuTI687EvP7Ct762";
		String pathname = outPdfsFilePath + "testAnyWriteDataSign.txt";
		byte[] signedPackage = FileUtils.readFileToByteArray(new File(pathname));
		ChannelMessage message = anySignClientTool.anyWriteDataVerify(signedPackage, contents);
		System.out.println("状态码：" + message.getStatusCode());
		System.out.println("状态信息：" + message.getStatusInfo());
		Assert.assertEquals("200", message.getStatusCode());
		if ("200".equals(message.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			ClientUtil.writeByteArrayToFile(new File(outPdfsFilePath + "testAnyWriteDataVerify.txt"), message.getBody());
		}
	}

	/**
	 * <p>一码一签，生成挑战码</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testAnyWriteChallengeCodeGenerate() throws Exception {
		// 签名人信息
		AnyWriteChallengeCodeReqMessage message = new AnyWriteChallengeCodeReqMessage();
		message.setSignerName("袁振朝");
		message.setSignerTelephone("13488824505");
		message.setIdCard("12345678901");
		message.setAlgorithm("RSA");
		// message.setAlgorithm("SM2");

		message.setPeriod(1000); // 设置缓存有效期，单位秒

		// 渠道号
		SignExtInfo signExtInfo = new SignExtInfo();
		signExtInfo.setBussChannel("999999");
		message.setSignExtInfo(signExtInfo);

		// 附件、证据
		List<cn.org.bjca.common.model.AttachmentInfo> attachmentInfos = new ArrayList<cn.org.bjca.common.model.AttachmentInfo>();
		cn.org.bjca.common.model.AttachmentInfo attachmentInfo = new cn.org.bjca.common.model.AttachmentInfo();
		attachmentInfo.setAttach(true);
		byte[] attachContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
		attachmentInfo.setAttachContent(attachContent);
		attachmentInfo.setAttachType(DocumentExtType.IMAGEGIF);
		attachmentInfo.setEvidenceHash("1234567890");
		attachmentInfos.add(attachmentInfo);
		for (int i = 0; i < 2; i++) {
			attachmentInfo = new cn.org.bjca.common.model.AttachmentInfo();
			attachmentInfo.setAttach(true);
			attachContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
			attachmentInfo.setAttachContent(attachContent);
			attachmentInfo.setAttachType(DocumentExtType.IMAGEGIF);
			attachmentInfo.setEvidenceHash("1234567890");
			attachmentInfos.add(attachmentInfo);
		}

		cn.org.bjca.common.model.AttachmentInfo evidence = new cn.org.bjca.common.model.AttachmentInfo();
		evidence.setEvidence(true);
		byte[] evidenceContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
		evidence.setAttachContent(evidenceContent);
		evidence.setAttachType(DocumentExtType.IMAGEGIF);
		evidence.setEvidenceHash("1234567890");
		attachmentInfos.add(evidence);
		message.setAttachmentInfos(attachmentInfos);
		for (int i = 0; i < 2; i++) {
			evidence = new cn.org.bjca.common.model.AttachmentInfo();
			evidence.setEvidence(true);
			evidenceContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
			evidence.setAttachContent(evidenceContent);
			evidence.setAttachType(DocumentExtType.IMAGEGIF);
			evidence.setEvidenceHash("1234567890");
			evidence.setIndex(1);
			attachmentInfos.add(evidence);
			message.setAttachmentInfos(attachmentInfos);
		}

		// 待签名PDF
		List<ChallengeCodePDFInfo> pdfInfos = new ArrayList<ChallengeCodePDFInfo>();
		ChallengeCodePDFInfo pdfinfo = new ChallengeCodePDFInfo();
		GeneratePDFInfo generatePDFInfo = new GeneratePDFInfo();
		byte[] docContent = FileUtils.readFileToByteArray(new File(testPdfFilePath));
		generatePDFInfo.setDocContent(docContent);
		generatePDFInfo.setDocumentExtType(DocumentExtType.PDF);
		pdfinfo.setGeneratePDFInfo(generatePDFInfo);
		// 设置签名位置信息
		pdfinfo.setSignSuleType("0");
		KWRuleInfo kwRuleInfo = new KWRuleInfo();
		kwRuleInfo.setKW("的");
		kwRuleInfo.setPageno("1");
		kwRuleInfo.setKWOffset("0");
		kwRuleInfo.setKWPos("0");
		kwRuleInfo.setKWXOffset("0");
		kwRuleInfo.setKWYOffset("0");
		pdfinfo.setKwRuleInfo(kwRuleInfo);
		pdfInfos.add(pdfinfo);
		message.setChallengeCodePDFInfos(pdfInfos);

		ChannelMessage channelMessage = anySignClientTool.anyWriteGenerateChallengeCode(message);
		System.out.println("状态码：" + channelMessage.getStatusCode());
		System.out.println("状态信息：" + channelMessage.getStatusInfo());
		Assert.assertEquals("200", channelMessage.getStatusCode());
		if ("200".equals(channelMessage.getStatusCode())) {// 成功
			System.out.println("成功");
			System.out.println(new String(channelMessage.getBody()));
		}

	}

	/**
	 * <p>一码多签，生成挑战码</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testAnyWriteChallengeCodeMultiSignGenerate() throws Exception {
		// 签名人信息
		AnyWriteChallengeCodeReqMessage message = new AnyWriteChallengeCodeReqMessage();
		message.setSignerName("袁振朝");
		message.setSignerTelephone("13488824505");
		message.setIdCard("12345678901");
		// message.setAlgorithm("RSA");
		message.setAlgorithm("SM2");

		// 渠道号
		SignExtInfo signExtInfo = new SignExtInfo();
		signExtInfo.setBussChannel("999999");
		message.setSignExtInfo(signExtInfo);

		// 附件、证据
		List<cn.org.bjca.common.model.AttachmentInfo> attachmentInfos = new ArrayList<cn.org.bjca.common.model.AttachmentInfo>();
		cn.org.bjca.common.model.AttachmentInfo attachmentInfo = new cn.org.bjca.common.model.AttachmentInfo();
		attachmentInfo.setAttach(true);
		byte[] attachContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
		attachmentInfo.setAttachContent(attachContent);
		attachmentInfo.setAttachType(DocumentExtType.IMAGEGIF);
		attachmentInfo.setEvidenceHash("1234567890");
		attachmentInfos.add(attachmentInfo);
		for (int i = 0; i < 2; i++) {
			attachmentInfo = new cn.org.bjca.common.model.AttachmentInfo();
			attachmentInfo.setAttach(true);
			attachContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
			attachmentInfo.setAttachContent(attachContent);
			attachmentInfo.setAttachType(DocumentExtType.IMAGEGIF);
			attachmentInfo.setEvidenceHash("1234567890");
			attachmentInfos.add(attachmentInfo);
		}

		cn.org.bjca.common.model.AttachmentInfo evidence = new cn.org.bjca.common.model.AttachmentInfo();
		evidence.setEvidence(true);
		byte[] evidenceContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
		evidence.setAttachContent(evidenceContent);
		evidence.setAttachType(DocumentExtType.IMAGEGIF);
		evidence.setEvidenceHash("1234567890");
		evidence.setIndex(1);
		attachmentInfos.add(evidence);
		message.setAttachmentInfos(attachmentInfos);
		for (int i = 0; i < 2; i++) {
			evidence = new cn.org.bjca.common.model.AttachmentInfo();
			evidence.setEvidence(true);
			evidenceContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
			evidence.setAttachContent(evidenceContent);
			evidence.setAttachType(DocumentExtType.IMAGEGIF);
			evidence.setEvidenceHash("1234567890");
			evidence.setIndex(1);
			attachmentInfos.add(evidence);
			message.setAttachmentInfos(attachmentInfos);
		}

		// 待签名PDF
		List<ChallengeCodePDFInfo> pdfInfos = new ArrayList<ChallengeCodePDFInfo>();
		ChallengeCodePDFInfo pdfinfo = new ChallengeCodePDFInfo();
		GeneratePDFInfo generatePDFInfo = new GeneratePDFInfo();
		byte[] docContent = FileUtils.readFileToByteArray(new File(testPdfFilePath));
		generatePDFInfo.setDocContent(docContent);
		generatePDFInfo.setDocumentExtType(DocumentExtType.PDF);
		pdfinfo.setGeneratePDFInfo(generatePDFInfo);
		// 设置签名位置信息
		pdfinfo.setSignSuleType("0");
		KWRuleInfo kwRuleInfo = new KWRuleInfo();
		kwRuleInfo.setKW("的");
		kwRuleInfo.setPageno("3");
		kwRuleInfo.setKWOffset("0");
		kwRuleInfo.setKWPos("0");
		kwRuleInfo.setKWXOffset("0");
		kwRuleInfo.setKWYOffset("0");
		pdfinfo.setKwRuleInfo(kwRuleInfo);
		pdfInfos.add(pdfinfo);

		// 添加多个文档，即是一码多签
		for (int i = 0; i < 9; i++) {
			// 添加多个文件
			ChallengeCodePDFInfo pdfinfo2 = new ChallengeCodePDFInfo();
			GeneratePDFInfo generatePDFInfo2 = new GeneratePDFInfo();
			byte[] docContent2 = FileUtils.readFileToByteArray(new File(testPdfFilePath));
			generatePDFInfo2.setDocContent(docContent2);
			generatePDFInfo2.setDocumentExtType(DocumentExtType.PDF);
			pdfinfo2.setGeneratePDFInfo(generatePDFInfo2);
			// 设置签名位置信息
			pdfinfo2.setSignSuleType("1");
			PosRuleInfo posRuleInfo = new PosRuleInfo();
			posRuleInfo.setPageno("1");
			posRuleInfo.setBottom("200");
			posRuleInfo.setLeft("200");
			posRuleInfo.setTop("200");
			posRuleInfo.setRight("200");

			pdfinfo2.setPosRuleInfo(posRuleInfo);
			pdfInfos.add(pdfinfo2);
		}
		message.setChallengeCodePDFInfos(pdfInfos);

		ChannelMessage channelMessage = anySignClientTool.anyWriteGenerateChallengeCode(message);
		System.out.println("状态码：" + channelMessage.getStatusCode());
		System.out.println("状态信息：" + channelMessage.getStatusInfo());
		Assert.assertEquals("200", channelMessage.getStatusCode());
		if ("200".equals(channelMessage.getStatusCode())) {// 成功
			System.out.println("成功");
			System.out.println(new String(channelMessage.getBody()));
		}

	}

	/**
	 * <p>带公章生成挑战码</p>
	 * @Description:
	 * @throws Exception
	 */
	@Test
	public void testAnyWriteChallengeCodeWithUnitSignGenerate() throws Exception {
		// 签名人信息
		AnyWriteChallengeCodeReqMessage message = new AnyWriteChallengeCodeReqMessage();
		message.setSignerName("费玥");
		message.setSignerTelephone("17701085294");
		message.setIdCard("12345678901");
		message.setAlgorithm("RSA");
		//		message.setAlgorithm("SM2");

		// 渠道号
		SignExtInfo signExtInfo = new SignExtInfo();
		signExtInfo.setBussChannel("999999");
		message.setSignExtInfo(signExtInfo);

		// 附件、证据
		List<cn.org.bjca.common.model.AttachmentInfo> attachmentInfos = new ArrayList<cn.org.bjca.common.model.AttachmentInfo>();
		cn.org.bjca.common.model.AttachmentInfo attachmentInfo = new cn.org.bjca.common.model.AttachmentInfo();
		attachmentInfo.setAttach(true);
		byte[] attachContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
		attachmentInfo.setAttachContent(attachContent);
		attachmentInfo.setAttachType(DocumentExtType.IMAGEGIF);
		attachmentInfo.setEvidenceHash("1234567890");
		attachmentInfos.add(attachmentInfo);

		cn.org.bjca.common.model.AttachmentInfo evidence = new cn.org.bjca.common.model.AttachmentInfo();
		evidence.setEvidence(true);
		byte[] evidenceContent = FileUtils.readFileToByteArray(new File(testImageFilePath));
		evidence.setAttachContent(evidenceContent);
		evidence.setAttachType(DocumentExtType.IMAGEGIF);
		evidence.setEvidenceHash("1234567890");
		evidence.setIndex(1);
		attachmentInfos.add(evidence);
		message.setAttachmentInfos(attachmentInfos);

		// 待签名PDF
		List<ChallengeCodePDFInfo> pdfInfos = new ArrayList<ChallengeCodePDFInfo>();
		ChallengeCodePDFInfo pdfinfo = new ChallengeCodePDFInfo();
		GeneratePDFInfo generatePDFInfo = new GeneratePDFInfo();
		byte[] docContent = FileUtils.readFileToByteArray(new File(testPdfFilePath));
		generatePDFInfo.setDocContent(docContent);
		generatePDFInfo.setDocumentExtType(DocumentExtType.PDF);
		pdfinfo.setGeneratePDFInfo(generatePDFInfo);
		// 设置签名位置信息
		pdfinfo.setSignSuleType("0");
		KWRuleInfo kwRuleInfo = new KWRuleInfo();
		kwRuleInfo.setKW("的");
		kwRuleInfo.setPageno("1");
		kwRuleInfo.setKWOffset("0");
		kwRuleInfo.setKWPos("0");
		kwRuleInfo.setKWXOffset("0");
		kwRuleInfo.setKWYOffset("0");
		pdfinfo.setKwRuleInfo(kwRuleInfo);
		pdfInfos.add(pdfinfo);

		message.setChallengeCodePDFInfos(pdfInfos);

		// 公章信息，使用签章规则
		List<CachetInfo> cachetInfos = new ArrayList<CachetInfo>();
		CachetInfo cachetInfo = new CachetInfo();
		cachetInfo.setTid("5E9217F50C3E491D");
		SignRuleInfo signRule = new SignRuleInfo();
		signRule.setRuleType("2"); // 签章规则方式
		cachetInfo.setSignRule(signRule);
		cachetInfos.add(cachetInfo);

		// 公章，使用外传图片，签名策略编号
		CachetInfo cachetInfo2 = new CachetInfo();
		cachetInfo2.setAppName("3F89508445039559");
		cachetInfo2.setImage("R0lGODlhZAAyAJEAAAAAAP///+0LC////yH5BAEAAAMALAAAAABkADIAAAL/nI+py+0Po5xG0IuzZqLbDYZi4nXDN6aqVKLrC5NtrFoefdNUXh2t+eL9gLrK8FgaIZFFxNL2u3xsxmcy5qrOUFGp9ZbdXE/Q8WzR3V2ZtS"
				                     + "+RzHPGM0S28giPj2Vz8fO+l5bH0UfnJnImJ5So+KbBhOfnmMeVROWz92hZt6U5mfhHGRK6hJE52JhWOBHFaMUKFusYiTkZgceoFRlWO4Tay"
				                     + "/sL69pXVtqwq5fb63VKq3uKVqy8uozcqfAsyRsYrXWLTUJpOTqX6y18rTx" + "+vM03azJty8KmbSrv8preDLp637+onT9YPU7s2xZKF6GB"
				                     +
				                     "/OCscJPPnzWEwQqiA0ZGocaFhBU9bTqkjlvAed8eQrSTDV8lkiUdxOMC7NCWgfJSuWR4shRLNWjeQbgIzVePiU02cvzp65LPotJwAvXINCXDcTCeYpkqqirWIBINCm2zFSxLlCmI4gBqr5xVkzvZIeK0FlBbr2bBtSsa15jYuGrnLn37tUjdhVz5Rj1cBbHixYwbO95QAAA7");
		SignRuleInfo signRuleInfo = new SignRuleInfo();
		signRuleInfo.setRuleType("0"); // 关键字
		KWInfo kwInfo = new KWInfo();
		kwInfo.setKW("的");
		kwInfo.setKWOffset("0");
		kwInfo.setKWPos("0");
		kwInfo.setPageno("1");
		kwInfo.setXOffset("0");
		kwInfo.setYOffset("0");
		signRuleInfo.setKWRule(kwInfo);
		cachetInfo2.setSignRule(signRuleInfo);
		cachetInfos.add(cachetInfo2);

		message.setIsUnit("true");
		message.setCachetInfos(cachetInfos);

		ChannelMessage channelMessage = anySignClientTool.anyWriteGenerateChallengeCode(message);
		System.out.println("状态码：" + channelMessage.getStatusCode());
		System.out.println("状态信息：" + channelMessage.getStatusInfo());
		Assert.assertEquals("200", channelMessage.getStatusCode());
		if ("200".equals(channelMessage.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			System.out.println(new String(channelMessage.getBody()));
		}

	}

	/**
	 * <p>testAnyWriteChallengeCodeSign</p>
	 * @Description:挑战码签名
	 * @throws Exception
	 */
	@Test
	public void testAnyWriteChallengeCodeSign() throws Exception {
		AnyWriteChallengeCodeReqMessage message = new AnyWriteChallengeCodeReqMessage();
		message.setTransId("cf409693-4bc5-4349-a803-e036f3025f6e");
		message.setChallengeCode("194129");
		message.setSignerTelephone("13488824505");
		message.setAlgorithm("SM2");
		long beginTime = System.currentTimeMillis();
		ChannelMessage channelMessage = anySignClientTool.anyWriteChallengeCodeSign(message);
		long endTime = System.currentTimeMillis();
		System.out.println((endTime - beginTime));
		System.out.println(new String(channelMessage.getHead()));
		System.out.println("状态码：" + channelMessage.getStatusCode());
		System.out.println("状态信息：" + channelMessage.getStatusInfo());
		Assert.assertEquals("200", channelMessage.getStatusCode());
		if ("200".equals(channelMessage.getStatusCode())) {// 成功
			System.out.println("成功,PDF保存路径:" + outPdfsFilePath);
			List<MessageBodyReference> messageBodyReferenceList = channelMessage.getMessageBodyReferenceList();
			MessageBodyReference messageBodyReference = null;
			for (int i = 0; i < messageBodyReferenceList.size(); i++) {
				messageBodyReference = messageBodyReferenceList.get(i);
				ClientUtil.writeByteArrayToFile(new File(outPdfsFilePath + "testAnyWriteChallengeCodeSign_" + i + ".pdf"), messageBodyReference.getFileBty());
			}
		}
	}

}
